﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Mosaik_complete_
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private delegate void SetTextDelegate(string text);


        #region bilder_zuschneiden
    
        string[] bildpfade_quelle;
        int seitenlänge;

        private void b_ordner_waehlen_1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folder = new FolderBrowserDialog();
            if (folder.ShowDialog() == DialogResult.OK)
            {
                tb_gewaehlter_ordner1.Text = folder.SelectedPath;
            }
        }

        private void b_bilder_suchen_Click(object sender, EventArgs e)
        {
            if (directory_and_file.exist_directory(tb_gewaehlter_ordner1.Text) == false)
            {
                MessageBox.Show("Ordner nicht gefunden!", "Fehler");
                return;
            }
            bildpfade_quelle = directory_and_file.get_pictures(tb_gewaehlter_ordner1.Text);
            l_bilderanzahl.Text = bildpfade_quelle.Length.ToString();
        }

        private void setText_l_statuslabel1(string text)
        {
            if (l_statuslabel1.InvokeRequired)
            {
                SetTextDelegate setTextDelegate = new SetTextDelegate(setText_l_statuslabel1);
                l_statuslabel1.Invoke(setTextDelegate, text);
            }
            else l_statuslabel1.Text = text;
        }

        private void b_bilder_zuschneiden_Click(object sender, EventArgs e)
        {
            if (cb_seitenlaenge.Text == "" || bildpfade_quelle == null) return;
            seitenlänge = Convert.ToInt32(cb_seitenlaenge.Text);
            pb_bilder_zuschneiden.Maximum = bildpfade_quelle.Length;
            pb_bilder_zuschneiden.Step = 1;
            bw_bilder_zuschneiden.RunWorkerAsync();
        }

        private void bw_bilder_zuschneiden_DoWork_1(object sender, DoWorkEventArgs e)
        {

            for (int i = 0; i < bildpfade_quelle.Length; i++)
            {
                Bildmanipulationen.bild_zuschneiden(bildpfade_quelle[i], seitenlänge);
                if (pb_bilder_zuschneiden.InvokeRequired)
                    pb_bilder_zuschneiden.Invoke(new MethodInvoker(pb_bilder_zuschneiden.PerformStep));
                else
                    pb_bilder_zuschneiden.PerformStep();

                setText_l_statuslabel1(i + " von " + bildpfade_quelle.Length + " bearbeitet.");
            }
            setText_l_statuslabel1(bildpfade_quelle.Length + " bearbeitet. --> fertig!");
        }

        

        #endregion

        #region bilder_analysieren

        string[] bildpfade_quelle_500x500;
        string dateispeicherort;
        Bildverwaltung verwaltung;

        private void b_ordner_waehlen_2_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folder = new FolderBrowserDialog();
            if (folder.ShowDialog() == DialogResult.OK)
            {
                tb_gewaehlter_ordner2.Text = folder.SelectedPath;
            }
        }

        private void b_analysedatei_erstellen_Click(object sender, EventArgs e)
        {
            verwaltung = new Bildverwaltung();
            if (directory_and_file.exist_directory(tb_gewaehlter_ordner2.Text))
            {
                bildpfade_quelle_500x500 = directory_and_file.get_pictures(tb_gewaehlter_ordner2.Text);
            }
            else
            {
                MessageBox.Show("Ordner nicht gefunden!", "Fehler");
                return;
            }
            pb_bilder_analysieren.Maximum = bildpfade_quelle_500x500.Length;
            pb_bilder_analysieren.Step = 1;

            SaveFileDialog fileplace = new SaveFileDialog();
            fileplace.Filter = "Analysedatei (*.dat)|*.dat";
            
            if (fileplace.ShowDialog() == DialogResult.OK)
            {
                dateispeicherort = fileplace.FileName;
            }

            bw_bilder_analysieren.RunWorkerAsync();
        }

        private void setText_l_statuslabel2(string text)
        {
            if (l_statuslabel2.InvokeRequired)
            {
                SetTextDelegate setTextDelegate = new SetTextDelegate(setText_l_statuslabel2);
                l_statuslabel2.Invoke(setTextDelegate, text);
            }
            else l_statuslabel2.Text = text;
        }

        private void bw_bilder_analysieren_DoWork1(object sender, DoWorkEventArgs e)
        {
            for (int i=0; i<bildpfade_quelle_500x500.Length; i++)
            {
                verwaltung.add_one_picture(bildpfade_quelle_500x500[i]);
                if (pb_bilder_analysieren.InvokeRequired)
                    pb_bilder_analysieren.Invoke(new MethodInvoker(pb_bilder_analysieren.PerformStep));
                else
                    pb_bilder_analysieren.PerformStep();
                setText_l_statuslabel2(i + " von " + bildpfade_quelle_500x500.Length + " Analysiert.");
            }

            FileStream file = new FileStream(dateispeicherort, FileMode.Create);
            BinaryFormatter bifo = new BinaryFormatter();
            bifo.Serialize(file, verwaltung);

            setText_l_statuslabel2(bildpfade_quelle_500x500.Length + " Analysiert. --> Fertig!");
            l_geladene_config.Text = dateispeicherort;
        }

        #endregion

        #region mosaik_erstellen

        string speicherort;
        Bitmap quellbild = null;
        int ausmasmultiplikator;

        private void b_config_laden_Click(object sender, EventArgs e)
        {
            OpenFileDialog dia_config = new OpenFileDialog();
            dia_config.Filter = "Analysedatei (*.dat)|*.dat";

            if (dia_config.ShowDialog() == DialogResult.OK)
            {
                FileStream file = new FileStream(dia_config.FileName, FileMode.Open);
                BinaryFormatter bifo = new BinaryFormatter();
                try
                {
                    verwaltung = (Bildverwaltung)bifo.Deserialize(file);
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                l_geladene_config.Text = dia_config.FileName;
            }
        }

        private void b_bild_laden_Click(object sender, EventArgs e)
        {
            OpenFileDialog opfi = new OpenFileDialog();
            opfi.Filter = "JPG (*.jpg)|*.jpg| JPEG (*.jpeg)|*.jpeg";

            if (opfi.ShowDialog() == DialogResult.OK)
            {
                tb_bildpfad.Text = opfi.FileName;
            }

            quellbild = new Bitmap(tb_bildpfad.Text);
        }

        private void cb_seitenlaenge_2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (quellbild == null)
                return;
            ausmasmultiplikator = Convert.ToInt32(cb_seitenlaenge_2.Text);
            l_gesamtausmas.Text = Convert.ToString(ausmasmultiplikator * quellbild.Width) + " x " + Convert.ToString(Convert.ToInt32(cb_seitenlaenge_2.Text) * quellbild.Height) + " Pixel";
        }

        private void b_mosaik_erstellen_Click(object sender, EventArgs e)
        {
            SaveFileDialog savidi = new SaveFileDialog();
            savidi.Filter = "JPG (*.jpg)|*.jpg";

            if (savidi.ShowDialog() == DialogResult.OK)
            {
                speicherort = savidi.FileName;
            }
            else
            {
                return;
            }

            pb_mosaik_erstellen.Maximum = quellbild.Width * quellbild.Height;
            pb_mosaik_erstellen.Step = 1;

            bw_mosaik_erstellen.RunWorkerAsync();
        }

        private void bw_mosaik_erstellen_DoWork(object sender, DoWorkEventArgs e)
        {

            Bitmap quellbild = new Bitmap(tb_bildpfad.Text);
            Bitmap mosaik_fertig = new Bitmap((Int32)(quellbild.Width * ausmasmultiplikator), (Int32)(quellbild.Height * ausmasmultiplikator), quellbild.PixelFormat);
            Random zufallszahl = new Random();

            for (int i = 1; i - 1 < quellbild.Height; i++)
            {
                for (int u = 1; u - 1 < quellbild.Width; u++)
                {
                    Color farbe = quellbild.GetPixel(u - 1, i - 1);
                    Bitmap einsatzbild = null;
                    string[] mögliche_bilder = verwaltung.finde_bild(farbe);

                    if (mögliche_bilder.Length != 0)
                    {
                        einsatzbild = new Bitmap(mögliche_bilder[zufallszahl.Next(mögliche_bilder.Length)]);
                        if (einsatzbild.Height != ausmasmultiplikator || einsatzbild.Width != ausmasmultiplikator)
                            einsatzbild = new Bitmap(einsatzbild, new Size(ausmasmultiplikator, ausmasmultiplikator));
                    }
                    int z_unten = 0;
                    for (int z = (i * ausmasmultiplikator - ausmasmultiplikator); z < (i * ausmasmultiplikator); z++)
                    {
                        int t_unten = 0;
                        for (int t = (u * ausmasmultiplikator - ausmasmultiplikator); t < (u * ausmasmultiplikator); t++)
                        {
                            if (mögliche_bilder.Length != 0)
                            {
                                mosaik_fertig.SetPixel(t, z, einsatzbild.GetPixel(t_unten, z_unten));
                            }
                            else
                            {
                                mosaik_fertig.SetPixel(t, z, farbe);
                            }
                            t_unten++;
                        }
                        z_unten++;
                    }
                    if (pb_mosaik_erstellen.InvokeRequired)
                        pb_mosaik_erstellen.Invoke(new MethodInvoker(pb_mosaik_erstellen.PerformStep));
                    else
                        pb_mosaik_erstellen.PerformStep();
                }
            }
            //hier sind die for dinger zu ende
            mosaik_fertig.Save(speicherort, System.Drawing.Imaging.ImageFormat.Jpeg);
        }

        #endregion



    }


}
